package org.theqcp.wow.api.wowhead;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.theqcp.wow.api.wowhead.parsers.EquipmentParser;
import org.theqcp.wow.model.api.ProgressListener;
import org.theqcp.wow.model.api.RemoteEquipmentAPI;
import org.theqcp.wow.model.exceptions.EquipmentNotFoundException;
import org.theqcp.wow.model.exceptions.ServiceUnavailableException;
import org.theqcp.wow.model.items.Equipment;
import org.theqcp.wow.utilities.http.HTTPRead;

/**
 * Connect to the wowhead xml stream.
 * 
 * @author angryundead
 *
 */
public class WowHead implements RemoteEquipmentAPI {

	public Equipment getEquipmentByID(String id, ProgressListener listener) throws ServiceUnavailableException, EquipmentNotFoundException {
				
		//equipment
		Equipment eq = null;
		
		//build url
		String urlBase = "http://www.wowhead.com/?item=";
		urlBase += id;
		urlBase += "&xml";
		
		//get XML response
		try {
			//get list of equipment (should only have one item anyway)
			List<Equipment> eqList = this.getEquipmentListFromURL(urlBase);
			
			//if the list has items, get the first one
			if(eqList != null && eqList.size() > 0) {
				eq = eqList.get(0);
			}
			
		} catch (MalformedURLException mfe) {
			//fail!
			if(listener != null) {
				listener.fail();
			}
			throw new IllegalArgumentException("The url was malformed.");
		} catch (IOException e) {
			//fail!
			if(listener != null) {
				listener.fail();
			}
			throw new ServiceUnavailableException("The service returned an malformed XML message or was not available.");
		}
		
		if(eq == null || eq.getItemName() == null || eq.getItemName().isEmpty()) {
			//fail!
			if(listener != null) {
				listener.fail();
			}
			throw new EquipmentNotFoundException("The equipment " + id + " could not be found.");
		}
		
		//complete!
		if(listener != null) {
			listener.updateProgress(100);
			listener.complete();
		}
		
		return eq;
	}
	
	public List<Equipment> getEquipmentByName(String name, ProgressListener listener) throws ServiceUnavailableException, EquipmentNotFoundException {
		
		//equipment
		List<Equipment> eqList = new ArrayList<Equipment>();
		
		//build url
		String urlBase = "http://www.wowhead.com/?item=";
		try {
			urlBase += URLEncoder.encode(name.toLowerCase().replace(" ", "+"),"utf8");
		} catch (UnsupportedEncodingException e1) {
			//return the empty list
			return eqList;
		}
		urlBase += "&xml";
		
		//get XML response
		try {
			//get list of equipment (should only have one item anyway)
			eqList = this.getEquipmentListFromURL(urlBase);			
		
		} catch (MalformedURLException mfe) {
			//fail!
			if(listener != null) {
				listener.fail();
			}			
			throw new IllegalArgumentException("The url was malformed.");
		} catch (IOException e) {
			//fail!
			if(listener != null) {
				listener.fail();
			}
			throw new ServiceUnavailableException("The service returned an malformed XML message or was not available.");
		}
		
		if(eqList == null || eqList.isEmpty()) {
			//fail!
			if(listener != null) {
				listener.fail();
			}
			
			throw new EquipmentNotFoundException("No equipment was found with the name: " + name);
		}
		
		//complete!
		if(listener != null) {
			listener.updateProgress(100);
			listener.complete();
		}
		
		//return
		return eqList;
	}
	
	public Equipment getEquipmentByID(String id)
			throws EquipmentNotFoundException, ServiceUnavailableException,
			IllegalArgumentException {
		return this.getEquipmentByID(id, null);
	}

	public List<Equipment> getEquipmentByName(String name) throws EquipmentNotFoundException,
			ServiceUnavailableException, IllegalArgumentException {
		// TODO Auto-generated method stub
		return this.getEquipmentByName(name,null);
	}

	private List<Equipment> getEquipmentListFromURL(String urlString) throws MalformedURLException, IOException {
		
		//get the url
		URL url = null;
		url = new URL(urlString);

		//create empty list by default
		List<Equipment> eqList = new ArrayList<Equipment>();
		
		//get xml message
		String xmlMessage = HTTPRead.getHTTPFromURL(url);
		
		//get list of equipment (should only have one item anyway)
		eqList = (new EquipmentParser()).parse(xmlMessage);
		
		//return the list
		return eqList;
	}
}
